package com.voltmao.service.application.contract;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.voltmao.persistent.mapper.*;
import com.voltmao.persistent.model.*;
import com.voltmao.service.application.sys.MessageTemplateServiceImpl;
import com.voltmao.service.application.sys.RegionServiceImpl;
import com.voltmao.webpro.frame.dto.DataPage;
import com.voltmao.webpro.utils.NumberUtils;
import com.voltmao.webpro.utils.PropertiesUtils;
import com.voltmao.webpro.utils.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 渠道商合同管理服务接口
 *
 * @author zhanglin
 * @date 2018/04/10
 */
@Service
public class ProviderServiceImpl {
    private static final Logger errorLogger = LoggerFactory.getLogger(ProviderServiceImpl.class);
    private static final Logger testLogger = LoggerFactory.getLogger("MY_TEST_LOGGER");

    @Autowired
    private ContractProviderMapper contractProviderMapper;
    @Autowired
    private ContractProviderGdbcMapper contractProviderGdbcMapper;
    @Autowired
    private ContractProviderGdbcMapsMapper contractProviderGdbcMapsMapper;
    @Autowired
    private ContractProviderSdnxMapper contractProviderSdnxMapper;
    @Autowired
    private ContractProviderAuditMapper contractProviderAuditMapper;
    @Autowired
    ProviderUserMapper providerUserMapper;
    @Autowired
    CorpEmployesUserMapper corpEmployesUserMapper;
    @Autowired
    RegionServiceImpl regionService;
    @Autowired
    MessageTemplateServiceImpl messageTemplateService;
    @Autowired
    SysUserInfoMapper sysUserInfoMapper;
    @Autowired
    ProviderAuditServiceImpl providerAuditService;

    /**
     * 合同表为主表，合同分页数据及查询
     * 附属了参数表，审核表信息
     * @param params 查询参数集合
     * @return DataPage分页集合
     */
    public DataPage selectContractDataPage(Map<String,Object> params){
        Date now = new Date();
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        testLogger.info("待查询参数："+params.toString());
        System.out.println("待查询参数："+params.toString());
        DataPage dataPage = new DataPage();
        int pageIndex = StringUtils.parseInt(params.get("pageNumber")+"", 1);
        int pageSize = StringUtils.parseInt(params.get("pageSize")+"", 20);

        ContractProviderCriteria example = new ContractProviderCriteria();
        ContractProviderCriteria.Criteria c = example.createCriteria();
        c.andIsDelEqualTo(0);
        if(!StringUtils.mapIsEmpty(params)){
            String dataId = "dataId";
            if(StringUtils.isNotEmpty(params.get(dataId))) {
                //主键查询
                c.andDataIdEqualTo(params.get(dataId)+"");
            }
            String contractNo = "contractNo";
            if(StringUtils.isNotEmpty(params.get(contractNo))) {
                //合同号模糊查询
                c.andContractNoLike("%" + params.get(contractNo) + "%");
            }
            String forProviderUser = "forProviderUser";
            if(StringUtils.isNotEmpty(params.get(forProviderUser))) {
                //渠道商主键
                c.andForProviderUserEqualTo(params.get(forProviderUser)+"");
            }
            String uploadFileUrl = "uploadFileUrl";
            if(StringUtils.isNotEmpty(params.get(uploadFileUrl))) {
                String noUpload = "1";
                String hasUpload = "2";
                //文件是否已上传
                if(noUpload.equals(params.get(uploadFileUrl)+"")){
                    c.andUploadFileUrlIsNull();
                }
                if(hasUpload.equals(params.get(uploadFileUrl)+"")){
                    c.andUploadFileUrlIsNotNull();
                }
            }
            String partyB = "partyB";
            if(StringUtils.isNotEmpty(params.get(partyB))) {
                //乙方公司名模糊查询
                c.andPartyBLike("%" + params.get(partyB) + "%");
            }
            String representativeName = "representativeName";
            if(StringUtils.isNotEmpty(params.get(representativeName))) {
                //法定代表人模糊查询
                c.andRepresentativeNameLike("%" + params.get(representativeName) + "%");
            }
            String partyAddress = "partyAddress";
            if(StringUtils.isNotEmpty(params.get(partyAddress))) {
                //地址模糊查询
                c.andPartyAddressLike("%" + params.get(partyAddress) + "%");
            }
            String incomeDivision = "incomeDivision";
            if(StringUtils.isNotEmpty(params.get(incomeDivision))) {
                //乙方收益分成比例查询
                c.andIncomeDivisionEqualTo(NumberUtils.parseInt(params.get(incomeDivision)+"",50));
            }
            String forDicHtlx = "forDicHtlx";
            if(StringUtils.isNotEmpty(params.get(forDicHtlx))) {
                //根据合同类型查询，1,2,3
                c.andForDicHtlxEqualTo(params.get(forDicHtlx)+"");
            }
        }
        example.setPageSize(pageSize);
        example.setLimitStart((pageIndex - 1) * pageSize);
        example.setOrderByClause("contract_provider.create_date desc");
        String auditType = "auditType";
        if(StringUtils.isNotEmpty(params.get(auditType))) {
            //按照审核状态类型查询0,1,2,3,4
            example.setAuditType(NumberUtils.parseInt(params.get(auditType)+"",0));
        }
        String employId = "employId";
        if(StringUtils.isNotEmpty(params.get(employId))) {
            //按照员工id查询，非总监,非渠道
            example.setEmployId(params.get(employId)+"");
        }
        //附带审核信息，单独处理
        List<Map<String, Object>> contracts = contractProviderMapper.selectMapByExampleAndType(example);
        //三类合同信息所有的(idDel=0)
        List<Map<String, Object>> cpSdnx = contractProviderSdnxMapper.selectMapByCPId(null);
        //添加1或者2类合同参数
        List<Map<String, Object>> gdbcs = contractProviderGdbcMapper.selectMapByCPId(null);
        long diff4 = System.currentTimeMillis() - now.getTime();
        long sec4 = diff4 % nd % nh % nm;
        testLogger.info("查询访问时间："+(sec4)+"ms");
        System.out.println("time2："+sec4);
        //处理审核信息
        for(Map<String, Object> tmpMap:contracts){
            Map<String, Object> audit = new HashMap<>(10);
            String auditDataId = "auditDataId";
            if(StringUtils.isNotEmpty(tmpMap.get(auditDataId))){
                audit.put("dataId", tmpMap.get(auditDataId));
                tmpMap.remove(auditDataId);
            }
            String auditForCorpEmployesUser = "auditForCorpEmployesUser";
            if(StringUtils.isNotEmpty(tmpMap.get(auditForCorpEmployesUser))){
                audit.put("forCorpEmployesUser", tmpMap.get(auditForCorpEmployesUser));
                tmpMap.remove(auditForCorpEmployesUser);
            }
            String auditAuditUserName = "auditAuditUserName";
            if(StringUtils.isNotEmpty(tmpMap.get(auditAuditUserName))){
                audit.put("auditUserName", tmpMap.get(auditAuditUserName));
                tmpMap.remove(auditAuditUserName);
            }
            String auditIsDel = "auditIsDel";
            if(StringUtils.isNotEmpty(tmpMap.get(auditIsDel))){
                audit.put("isDel", tmpMap.get(auditIsDel));
                tmpMap.remove(auditIsDel);
            }
            String auditCreateDate = "auditCreateDate";
            if(StringUtils.isNotEmpty(tmpMap.get(auditCreateDate))){
                audit.put("createDate", tmpMap.get(auditCreateDate));
                tmpMap.remove(auditCreateDate);
            }
            String auditUpdateDate = "auditUpdateDate";
            if(StringUtils.isNotEmpty(tmpMap.get(auditUpdateDate))){
                audit.put("updateDate", tmpMap.get(auditUpdateDate));
                tmpMap.remove(auditUpdateDate);
            }
            String auditForDicShzt = "auditForDicShzt";
            if(StringUtils.isNotEmpty(tmpMap.get(auditForDicShzt))){
                audit.put("forDicShzt", tmpMap.get(auditForDicShzt));
                tmpMap.remove(auditForDicShzt);
            }
            String auditForDicShztName = "auditForDicShztName";
            if(StringUtils.isNotEmpty(tmpMap.get(auditForDicShztName))){
                audit.put("forDicShztName", tmpMap.get(auditForDicShztName));
                tmpMap.remove(auditForDicShztName);
            }
            String auditForContractProvider = "auditForContractProvider";
            if(StringUtils.isNotEmpty(tmpMap.get(auditForContractProvider))){
                audit.put("forContractProvider", tmpMap.get(auditForContractProvider));
                tmpMap.remove(auditForContractProvider);
            }
            String auditAuditReason = "auditAuditReason";
            if(StringUtils.isNotEmpty(tmpMap.get(auditAuditReason))){
                audit.put("auditReason", tmpMap.get(auditAuditReason));
                tmpMap.remove(auditAuditReason);
            }
            if (!StringUtils.mapIsEmpty(audit)) {
                tmpMap.put("auditType", audit.get("forDicShzt"));
                tmpMap.put("audit", audit);
            } else {
                tmpMap.put("auditType", 0);
            }
            //添加按年化合同金额
            //添加按年化签约量
            String dataId = tmpMap.get("dataId")+"";
            if("3".equals(tmpMap.get("forDicHtlx")+"")){
                //追加3类合同参数
                List<Map<String, Object>> mapItems = cpSdnx.stream()
                        .filter(mapItem->dataId.equals(mapItem.get("forContractProvider")+""))
                        .collect(Collectors.toList());
                if(StringUtils.isNotEmpty(mapItems) && mapItems.size()>0){
                    tmpMap.put("args",mapItems);
                } else{
                    throw new NullPointerException("主键为："+dataId+"的合同没有设置参数");
                }
            }else{
                List<Map<String, Object>> mapItems = gdbcs.stream()
                        .filter(mapItem->dataId.equals(mapItem.get("forContractProvider")+""))
                        .collect(Collectors.toList());
                mapItems.stream().forEach(item->item.remove("forContractProvider"));
                tmpMap.put("args",mapItems);
                tmpMap.put("forDicFclx", mapItems.get(0).get("forDicFclx"));
            }
        }
        dataPage.pageindex= pageIndex;
        dataPage.pagesize = pageSize;
        dataPage.rows = contracts;
        dataPage.total = contractProviderMapper.countByExample(example);

        long diff = System.currentTimeMillis() - now.getTime();
        long sec = diff % nd % nh % nm;
        testLogger.info("查询访问时间："+sec+"ms");
        System.out.println("time2："+sec);
        return dataPage;
    }

    /**
     * 获取合同审核状态数量
     * @param auditType 审核类型
     * @return 数量
     */
    public int countToBeAudit(int auditType){
        ContractProviderCriteria example = new ContractProviderCriteria();
        ContractProviderCriteria.Criteria c = example.createCriteria();
        c.andIsDelEqualTo(0);
        int isSure = 2;
        if(auditType == isSure){
            c.andUploadFileUrlIsNotNull();
        }
        example.setAuditType(auditType);
        return contractProviderMapper.countByExample(example);
    }
    /**
     * 新增或修改合同初次生成相关表
     * 根据传进来的参数生成
     * 合同表
     * 分成类型表gdbc,及映射表
     * 固定分成表sdnx
     * @param params 新增或修改所需参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertOrUpdateContractArgs(Map<String, Object> params){
        testLogger.info("新增或修改传递参数："+params.toString());
        System.out.println("新增或修改传递参数："+params.toString());
        String toId = sysUserInfoMapper.getZJName();
        //新增所有表
        //type=0,类型不存在
        //type=1,类型为基本电费托管模板-按全年签约量、年化合同金额
        //type=2,类型为基本电费托管模板-固定分成
        //type=3,类型为能效信息管理模板
        final String insert = "INSERT";
        final String update = "UPDATE";
        final Integer type1 = 1;
        final Integer type2 = 2;
        final Integer type3 = 3;
        String flag = params.get("flag")+"";
        int type = NumberUtils.parseInt(params.get("type")+"",0);
        if(insert.equals(flag)){
            //新增合同记录
            JSONObject tmpContract = JSONObject.parseObject(params.get("ContractProvider")+"");
            //目前只有审核通过的渠道商才能新增合同
            String[] shzts = {"2", "3"};
            String forProviderUser = tmpContract.getString("forProviderUser");
            boolean isPass = providerUserMapper.getAuthByQdshzt(forProviderUser, shzts);
            if(!isPass){
                errorLogger.error("渠道商ID="+forProviderUser+"的用户审核未通过");
                testLogger.info("渠道商ID="+forProviderUser+"的用户审核未通过");
                System.out.println("渠道商ID="+forProviderUser+"的用户审核未通过");
                throw new IllegalArgumentException("渠道商审核未通过");
            }
            ContractProvider cp = (ContractProvider) PropertiesUtils.mapToObject(tmpContract, ContractProvider.class);
            cp.setDataId(StringUtils.uuid36());
            cp.setForDicHtlx(params.get("type")+"");
            cp.setCreateDate(new Date());
            //默认启用
            cp.setIsDel(0);
            contractProviderMapper.insert(cp);
            //员工新增合同，通知发给总监
            String fromId = providerUserMapper.selectByPrimaryKey(forProviderUser).getForCorpEmployesUser();
            messageTemplateService.contractAdd(fromId, toId, forProviderUser);
            if(type==type3){
                //新增合同sdnx记录
                JSONObject tmpContractSdnx = JSONObject.parseObject(params.get("ContractProviderSdnx")+"");
                ContractProviderSdnx cpSdnx = (ContractProviderSdnx) PropertiesUtils.mapToObject(tmpContractSdnx, ContractProviderSdnx.class);
                cpSdnx.setDataId(StringUtils.uuid36());
                cpSdnx.setForContractProvider(cp.getDataId());
                contractProviderSdnxMapper.insertSelective(cpSdnx);
            }
            if(type==type1 || type ==type2){
                JSONArray array = JSONArray.parseArray(StringUtils.splitArray(params.get("args")+""));

                for(int i=0;i<array.size();i++){
                    JSONObject tmpObj = array.getJSONObject(i);
                    ContractProviderGdbc cpGdbc = JSONObject.parseObject(tmpObj.toJSONString(), ContractProviderGdbc.class);
                    cpGdbc.setDataId(StringUtils.uuid36());

                    contractProviderGdbcMapper.insertSelective(cpGdbc);
                    //新增合同gdbc映射记录
                    ContractProviderGdbcMaps cpgMaps = new ContractProviderGdbcMaps();
                    cpgMaps.setDataId(StringUtils.uuid36());
                    cpgMaps.setForContractProvider(cp.getDataId());
                    cpgMaps.setForContractProviderGdbc(cpGdbc.getDataId());
                    contractProviderGdbcMapsMapper.insert(cpgMaps);
                }
            }
            //异步生成初版pdf
            providerAuditService.test(cp.getDataId());
        }
        if(update.equals(flag)){
            //修改合同主表
            String contractProvider = "ContractProvider";
            if(StringUtils.isNotEmpty(params.get(contractProvider))){
                JSONObject tmpContract = JSONObject.parseObject(params.get(contractProvider)+"");
                ContractProvider cp = (ContractProvider) PropertiesUtils.mapToObject(tmpContract, ContractProvider.class);
                String dataId = cp.getDataId();
                ContractProvider cp2 = contractProviderMapper.selectByPrimaryKey(dataId);
                cp.setUpdateDate(new Date());
                if(!cp2.getForDicHtlx().equals(type+"")){
                    //目前不可修改合同类型
                    errorLogger.error("目前不可修改合同类型");
                    testLogger.info("目前不可修改合同类型");
                    System.out.println("目前不可修改合同类型");
                    throw new IllegalStateException("目前不可修改合同类型");
                }
                //发送消息
                if(!StringUtils.isEmpty(cp.getUploadFileUrl())) {
                    String providerId = cp2.getForProviderUser();
                    String fromId = providerUserMapper.selectByPrimaryKey(providerId).getForCorpEmployesUser();
                    messageTemplateService.contractUploadAgain(fromId, toId, providerId);
                }
                contractProviderMapper.updateByPrimaryKeySelective(cp);
            }
            //修改合同sdnx记录
            String contractProviderSdnx ="ContractProviderSdnx";
            if(type==type3 && StringUtils.isNotEmpty(params.get(contractProviderSdnx))){
                JSONObject tmpContractSdnx = JSONObject.parseObject(params.get(contractProviderSdnx)+"");
                ContractProviderSdnx cpSdnx = (ContractProviderSdnx) PropertiesUtils.mapToObject(tmpContractSdnx, ContractProviderSdnx.class);
                contractProviderSdnxMapper.updateByPrimaryKeySelective(cpSdnx);
            }
            //修改合同gdbc记录
            boolean in1Or2 = (type==2 || type==1);
            boolean hasArgs = StringUtils.isNotEmpty(params.get("args"));
            if(in1Or2 && hasArgs){
                JSONArray array = JSONArray.parseArray(StringUtils.splitArray(params.get("args")+""));
                for(int i=0;i<array.size();i++) {
                    JSONObject tmpObj = array.getJSONObject(i);
                    ContractProviderGdbc cpGdbc = (ContractProviderGdbc) PropertiesUtils.mapToObject(tmpObj, ContractProviderGdbc.class);
                    contractProviderGdbcMapper.updateByPrimaryKeySelective(cpGdbc);
                }
            }
        }
        //此处单独处理初审不通过的情况
        String changeAudit = "changeAudit";
        if(StringUtils.isNotEmpty(params.get(changeAudit))){
            String needChange = "1";
            String contractId = "contractId";
            if(needChange.equals(params.get(changeAudit)+"")){
                //员工重置合同状态为未审核
                ContractProvider cp =contractProviderMapper.selectByPrimaryKey(params.get(contractId)+"");
                String providerId = cp.getForProviderUser();
                String fromId = providerUserMapper.selectByPrimaryKey(providerId).getForCorpEmployesUser();
                messageTemplateService.contractTJAgain(fromId, toId, providerId);
                //删除审核记录
                ContractProviderAudit cpAudit = contractProviderAuditMapper.selectByCPId(params.get(contractId)+"", 0);
                cpAudit.setIsDel(1);
                cpAudit.setUpdateDate(new Date());
                contractProviderAuditMapper.updateByPrimaryKeySelective(cpAudit);
            }
            //异步生成初版pdf
            providerAuditService.test(params.get(contractId)+"");
        }
    }

    /**
     * 根据合同主键使isDel=1
     * @param dataId 合同主键
     * @return 更新数量
     */

    @Transactional(rollbackFor = Exception.class)
    public int deleteContractProvider(String dataId){
        testLogger.info("待删除主键："+dataId);
        System.out.println("待删除主键："+dataId);
        ContractProvider cp = contractProviderMapper.selectByPrimaryKey(dataId);
        cp.setUpdateDate(new Date());
        cp.setIsDel(1);
        //查询是否有对应审核记录，有则删除
        ContractProviderAudit cpAudit = contractProviderAuditMapper.selectByCPId(dataId, 0);
        if(StringUtils.isNotEmpty(cpAudit)){
            cpAudit.setUpdateDate(new Date());
            cpAudit.setIsDel(1);
            String noDelete = "2";
            if(cpAudit.getForDicShzt().equals(noDelete)){
                throw new IllegalStateException("禁止删除");
            }
            contractProviderAuditMapper.updateByPrimaryKey(cpAudit);
        }
        return contractProviderMapper.updateByPrimaryKey(cp);
    }

    /**
     * 根据合同Id删除对应合同
     * 对应的参数表，映射表
     * 审核表
     * 暂时用不上，执行真正删除
     * @param dataId 合同主键
     */

    @Transactional(rollbackFor = Exception.class)
    public void deleteContract(String dataId){
        //删除gdbc和map
        ContractProviderGdbcMapsCriteria example = new ContractProviderGdbcMapsCriteria();
        ContractProviderGdbcMapsCriteria.Criteria c = example.createCriteria();
        c.andForContractProviderEqualTo(dataId);
        List<ContractProviderGdbcMaps> lists = contractProviderGdbcMapsMapper.selectByExample(example);
        if(StringUtils.isNotEmpty(lists) || lists.size() > 0){
            for(ContractProviderGdbcMaps item:lists){
                //必须先删除map，外键约束
                contractProviderGdbcMapsMapper.deleteByPrimaryKey(item.getDataId());
                contractProviderGdbcMapper.deleteByPrimaryKey(item.getForContractProviderGdbc());
            }
        }
        //删除sdnx
        ContractProviderSdnxCriteria example2 = new ContractProviderSdnxCriteria();
        ContractProviderSdnxCriteria.Criteria c2 = example2.createCriteria();
        c2.andForContractProviderEqualTo(dataId);
        contractProviderSdnxMapper.deleteByExample(example2);
        //删除审核
        ContractProviderAuditCriteria example3 = new ContractProviderAuditCriteria();
        ContractProviderAuditCriteria.Criteria c3 = example3.createCriteria();
        c3.andForContractProviderEqualTo(dataId);
        contractProviderAuditMapper.deleteByExample(example3);
        //删除合同
        contractProviderMapper.deleteByPrimaryKey(dataId);
    }
}
